<?php
/**
 * Created by PhpStorm.
 * User: liuchenbin
 * Date: 2018/10/17
 * Time: 14:43
 */

namespace app\admin\controller;

use think\Db;
use think\facade\Config;
use think\facade\Session;

class MakeCode extends BaseController
{

    protected $module = 'admin';    // 生成目录(默认admin)
    protected $appPath;             // 应用目录
    protected $modulePath;          // 模块目录
    protected $controllerPath;      // 控制器目录
    protected $viewPath;            // 视图目录
    protected $dbModelPath;         // 数据模型目录

    protected $templateVersions = 'v1';    // 模板版本
    protected $templatePath;        // 模板目录

    protected $databaseName;        // 数据库名称
    protected $tableName;           // 数据表名称
    protected $tableInfo;           // 数据表信息- 二维数组 - 字段[COLUMN_NAME],备注[COLUMN_COMMENT]

    protected $className;           // 类名称 - 去掉表前缀，大驼峰命名
    protected $viewName;            // 视图目录名称 - 去掉前缀,小写，以符号下划线 _ 链接

    protected $isCover;

    protected $msg;


    public function initialize()
    {
        $this->appPath = '../application/';
        $this->dbModelPath = $this->appPath.'common/model/';
        $this->templatePath = $this->appPath.'common/template/'.$this->templateVersions.'/';
        $this->modulePath = $this->appPath.$this->module.'/';
        $this->controllerPath = $this->modulePath.'controller/';
        $this->viewPath = $this->modulePath.'view/';

        parent::initialize(); // TODO: Change the autogenerated stub
    }

    /**
     * 生成CURD
     */
    public function curd()
    {
        $request = $this->request;
        if ($request->isPost()){
            $data = $request->post();
            Session::flash('postdata',$data);

            // 是否覆盖
            $this->isCover = $data['cover'];
            // 处理名称
            $this->name($data['tableName']);
            // 处理数据表信息
            $this->dbTable($data['tableName']);
            // 开始生成
            $this->make($data['create']);
        }
        // 提示信息
        $this->assign('msg',$this->msg);

        $postdata = Session::get('postdata');
        $this->assign('postdata',$postdata);

        $dbTables = Db::query("SHOW TABLE STATUS");
        $this->assign('dbTables',$dbTables);

        return $this->fetch();

    }

    public function name($name)
    {
        $nameArray = array_map('ucfirst', explode('_', $name));;
        unset($nameArray[0]);
        $this->className = implode($nameArray);
        $this->viewName = strtolower(implode('_',$nameArray));
    }

    public function dbTable($tableName)
    {
        // 数据库名称
        $this->databaseName = Config::get()['database']['database'];
        // 获取表备注
        $table = Db::query("SHOW TABLE STATUS LIKE '$tableName'");

        $this->tableName = $tableName;
        $this->tableComment = $table[0]['Comment'];

        // 获取表字段名称与备注
        $this->tableInfo = Db::query("SELECT COLUMN_NAME,column_comment FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '$tableName' AND TABLE_SCHEMA = '$this->databaseName' ORDER BY ORDINAL_POSITION");
    }

    public function make($create)
    {
        $createArray = array_keys($create);
        // 生成数据模型
        if (in_array('dbmodel',$createArray)) {
            $this->makeDbModel();
        }
        // 生成控制器
        if (in_array('controller',$createArray)) {
            $this->makeController();
        }
        // 生成列表视图
        if (in_array('index',$createArray)) {
            $this->makeIndex();
        }
        // 生成表单视图
        if (in_array('form',$createArray)) {
            $this->makeForm();
        }
    }

    /**
     * 生成数据模型
     */
    public function makeDbModel()
    {
        $template = file_get_contents($this->templatePath.'dbmodel.tpl');
        $column = '';
        foreach ($this->tableInfo as $k =>$v) {
            $column .= '* @property string $'.$v['COLUMN_NAME'].' '.$v['COLUMN_COMMENT'].'.'.PHP_EOL;

        }
        # 占位符们
        $search = ['%tableName%','%className%','%column%'];
        $replace = [$this->tableName,$this->className,$column];
        # 替换模板
        $content = str_replace($search, $replace, $template);

        # 文件路径
        $fileFath = $this->dbModelPath.$this->className.'.php';

        # 开始生成
        if ($this->isFile($fileFath)){
            file_put_contents($fileFath,$content);
            $this->msg['succeed'][] = '生成数据模型：'.$this->className.'.php'.'成功！文件路径：'.$fileFath;
        }else{
            $this->msg['error'][] = '文件已经存在！文件路径：'.$fileFath;
        }
    }
    /**
     * 生成控制器
     */
    public function makeController()
    {
        # 获取模板
        $template = file_get_contents($this->templatePath.'controller.tpl');

        # 是否递归
        if (input('recursion') == 1){
            $recursionYes = '';
            $recursionNo = '#';
        }else{
            $recursionYes = '#';
            $recursionNo = '';
        }

        # 占位符们
        $search = ['%className%','%recursionYes%','%recursionNo%','%module%'];
        $replace = [$this->className,$recursionYes,$recursionNo,$this->module];
        # 替换模板
        $content = str_replace($search, $replace, $template);

        # 文件路径
        $fileFath = $this->controllerPath.$this->className.'.php';

        # 开始生成
        if ($this->isFile($fileFath)){
            file_put_contents($fileFath,$content);
            $this->msg['succeed'][] = '生成控制器：'.$this->className.'.php'.'成功！文件路径：'.$fileFath;
        }else{
            $this->msg['error'][] = '文件已经存在！文件路径：'.$fileFath;
        }

    }
    /**
     * 生成列表视图
     */
    public function makeIndex()
    {
        # 获取模板
        $template = file_get_contents($this->templatePath.'index.tpl');

        $td = $th = '';
        foreach ($this->tableInfo as $kay => $value) {
            if (!empty($value['COLUMN_COMMENT'])) {
                $th .= '<th>'.$value['COLUMN_COMMENT'].'</th>'.PHP_EOL;
            }else{
                $th .= '<th>'.$value['COLUMN_NAME'].'</th>'.PHP_EOL;
            }
            if ($value['COLUMN_NAME'] == 'icon'){
                $td .= '<td><i class="fa fa-{$vo.'.$value['COLUMN_NAME'].'}"></i></td>'.PHP_EOL;
            }else{
                $td .= '<td>{$vo.'.$value['COLUMN_NAME'].'}</td>'.PHP_EOL;
            }
        }

        # 占位符们
        $search = ['%th%','%td%'];
        $replace = [$th,$td];
        # 替换模板
        $content = str_replace($search, $replace, $template);

        # 文件路径
        $dirPath = $this->viewPath.$this->viewName;
        $filePath = $dirPath.'/index.html';
        $this->isDir($dirPath);
        # 开始生成
        if ($this->isFile($filePath)){
            file_put_contents($filePath,$content);
            $this->msg['succeed'][] = '生成列表视图：index.html 成功！文件路径：'.$filePath;
        }else{
            $this->msg['error'][] = '文件已经存在！文件路径：'.$filePath;
        }

    }

    /**
     * 生成表单
     */
    public function makeForm()
    {

        # 获取模板
        $template = file_get_contents($this->templatePath.'form.tpl');

        $input = '';
        foreach ($this->tableInfo as $kay => $value) {
            if ($value['COLUMN_NAME'] == 'id') {
                $input .= '
                    <input type="hidden" name="id" value="{$model.id|default=\'\'}">
                '.PHP_EOL;
            } else {
                $input .= '
                    <div class="layui-form-item">
                        <label class="layui-form-label">'.$value['COLUMN_COMMENT'].'</label>
                        <div class="layui-input-block">
                            <input type="text" name="'.$value['COLUMN_NAME'].'" value="{$model.'.$value['COLUMN_NAME'].'|default=\'\'}" required  lay-verify="required" placeholder="请输入'.$value['COLUMN_COMMENT'].'" autocomplete="off" class="layui-input">
                        </div>
                    </div>
                '.PHP_EOL;
            }

        }


        # 占位符们
        $search = ['%input%'];
        $replace = [$input];
        # 替换模板
        $content = str_replace($search, $replace, $template);
        # 文件路径
        $dirPath = $this->viewPath.$this->viewName;
        $filePath = $dirPath.'/form.html';
        $this->isDir($dirPath);
        # 开始生成
        if ($this->isFile($filePath)){
            file_put_contents($filePath,$content);
            $this->msg['succeed'][] = '生成表单视图：form.html 成功！文件路径：'.$filePath;
        }else{
            $this->msg['error'][] = '文件已经存在！文件路径：'.$filePath;
        }

    }

    /**
     * 文件是否存在，是否覆盖生成
     * @param $filePath
     * @return bool
     */
    public function isFile($filePath)
    {
        if ($this->isCover == 1){
            return true;
        }
        if ($this->isCover == 2){
            if (!is_file($filePath)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 目录是否存在，不存在则创建
     * @param $dir
     */
    public function isDir($dir)
    {
        if (!is_dir($dir)){
            mkdir($dir,0777,true);
        }
    }

}